package de.sendorian.app.forumArchive;


import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;

import org.joda.time.DateTime;

import de.sendorian.app.forumArchive.domain.Forum;
import de.sendorian.app.forumArchive.domain.Post;
import de.sendorian.app.forumArchive.domain.Topic;
import de.sendorian.app.forumArchive.finder.Finder;
import de.sendorian.app.forumArchive.renamer.FileRenamer;
import de.sendorian.app.forumArchive.repository.ForumRepository;
import de.sendorian.db.DAO;

public class ArchiveBuilder {

	private static Logger logger = Logger.getLogger(ArchiveBuilder.class.getName());


	public static void main(String[] args) throws IOException {
		configureLogging();
		ForumRepository forumRepository = new ForumRepository();

		Config config = Config.get();
		Finder<Forum, Topic> topicFinder = config.getTopicFinder().withFilter(
		    config.getTopicMatcher());
		Finder<Topic, Post> postFinder = config.getPostFinder();

		List<Forum> forums = config.getForumFinder().find(config.getBaseUrl());
		for (Forum forum : forums) {
			Forum persistenForum = forumRepository.findByName(forum.getName());
			if (persistenForum != null) {
				forum = persistenForum;
			}

			logger.log(Level.INFO, "Finding topics for forum \"" + forum.getName() + "\"");
			List<Topic> topics = topicFinder.find(forum);

			for (Topic topic : topics) {
				int persistentTopicIndex = forum.getTopics().indexOf(topic);
				if (persistentTopicIndex > -1) {
					Topic persistentTopic = forum.getTopics().get(persistentTopicIndex);
					DateTime persistentLastChange = new DateTime(persistentTopic.getLastPost());
					DateTime onlineLastChange = new DateTime(topic.getLastPost());
					if (onlineLastChange.isAfter(persistentLastChange)) {
						logger.log(Level.INFO, "Updating posts for topic \"" + topic.getName()
						    + "\"");
						List<Post> posts = postFinder.find(topic);
						topic.setPosts(posts);
						forum.getTopics().remove(persistentTopicIndex);
						forum.getTopics().add(topic);
					} else {
						logger.log(Level.INFO, "Topic \"" + topic.getName()
						    + "\" is already contained in cache.");
					}

				} else {
					List<Post> posts = postFinder.find(topic);
					topic.setPosts(posts);
					forum.getTopics().add(topic);
				}
			}
			DAO.saveOrUpdate(forum);
		}

		forums = new ForumRepository().findAll();
		FileRenamer renamer = config.getDefaultRenamer();
		new Downloader(config.getPostMatcher(), config.getTopicMatcher(), renamer)
		    .downloadForums(forums);

		DAO.shutdownDatabase();
		logger.log(Level.INFO, "Finished!");
	}


	private static void configureLogging() {
		InputStream ins = ArchiveBuilder.class.getResourceAsStream("/META-INF/logging.properties");
		LogManager logManager = LogManager.getLogManager();
		try {
			logManager.readConfiguration(ins);
		} catch (Exception e) {
			System.err
			    .println("Cannot load logging.properties! " + "Logging will NOT be possible!");
			e.printStackTrace();
		}
	}
}
